home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / uemlsrc.arc / window.c < prev    next >
C/C++ Source or Header  |  1987-08-24  |  12KB  |  400 lines

  1. /*
  2.  * Window management.
  3.  * Some of the functions are internal,
  4.  * and some are attached to keys that the
  5.  * user actually types.
  6.  */
  7. #include        <stdio.h>
  8. #include        "ed.h"
  9.  
  10. /*
  11.  * Reposition dot in the current
  12.  * window to line "n". If the argument is
  13.  * positive, it is that line. If it is negative it
  14.  * is that line from the bottom. If it is 0 the window
  15.  * is centered (this is what the standard redisplay code
  16.  * does). With no argument it defaults to 1. Bound to
  17.  * M-!. Because of the default, it works like in
  18.  * Gosling.
  19.  */
  20. reposition(f, n)
  21. register int f, n;
  22. {
  23.         curwp->w_force = n;
  24.         curwp->w_flag |= WFFORCE;
  25.         return (TRUE);
  26. }
  27.  
  28. /*
  29.  * Refresh the screen. With no
  30.  * argument, it just does the refresh. With an
  31.  * argument it recenters "." in the current
  32.  * window. Bound to "C-L".
  33.  */
  34. refresh(f, n)
  35. register int f, n;
  36. {
  37.         if (f == FALSE)
  38.                 sgarbf = TRUE;
  39.         else {
  40.                 curwp->w_force = 0;             /* Center dot.          */
  41.                 curwp->w_flag |= WFFORCE;
  42.         }
  43.         return (TRUE);
  44. }
  45.  
  46. /*
  47.  * The command make the next
  48.  * window (next => down the screen)
  49.  * the current window. There are no real
  50.  * errors, although the command does
  51.  * nothing if there is only 1 window on
  52.  * the screen. Bound to "C-X C-N".
  53.  */
  54. nextwind(f, n)
  55. register int f, n;
  56. {
  57.         register WINDOW *wp;
  58.         register WINDOW *wp2;
  59.  
  60.         if ((wp=curwp->w_wndp) == NULL)
  61.                 wp = wheadp;
  62.         curwp = wp;
  63.         curbp = wp->w_bufp;
  64.         upmode();
  65.         return (TRUE);
  66. }
  67.  
  68. /*
  69.  * This command makes the previous
  70.  * window (previous => up the screen) the
  71.  * current window. There arn't any errors,
  72.  * although the command does not do a lot
  73.  * if there is 1 window.
  74.  */
  75. prevwind(f, n)
  76. register int f, n;
  77. {
  78.         register WINDOW *wp1;
  79.         register WINDOW *wp2;
  80.  
  81.         wp1 = wheadp;
  82.         wp2 = curwp;
  83.         if (wp1 == wp2)
  84.                 wp2 = NULL;
  85.         while (wp1->w_wndp != wp2)
  86.                 wp1 = wp1->w_wndp;
  87.         curwp = wp1;
  88.         curbp = wp1->w_bufp;
  89.         upmode();
  90.         return (TRUE);
  91. }
  92.  
  93. /*
  94.  * This command moves the current
  95.  * window down by "arg" lines. Recompute
  96.  * the top line in the window. The move up and
  97.  * move down code is almost completely the same;
  98.  * most of the work has to do with reframing the
  99.  * window, and picking a new dot. We share the
  100.  * code by having "move down" just be an interface
  101.  * to "move up". Magic. Bound to "C-X C-N".
  102.  */
  103. mvdnwind(f, n)
  104. register int    f, n;
  105. {
  106.         return (mvupwind(f, -n));
  107. }
  108.  
  109. /*
  110.  * Move the current window up by "arg"
  111.  * lines. Recompute the new top line of the window.
  112.  * Look to see if "." is still on the screen. If it is,
  113.  * you win. If it isn't, then move "." to center it
  114.  * in the new framing of the window (this command does
  115.  * not really move "."; it moves the frame). Bound
  116.  * to "C-X C-P".
  117.  */
  118. mvupwind(f, n)
  119. register int    f, n;
  120. {
  121.         register LINE   *lp;
  122.         register int    i;
  123.  
  124.         lp = curwp->w_linep;
  125.         if (n < 0) {
  126.                 while (n++ && lp!=curbp->b_linep)
  127.                         lp = lforw(lp);
  128.         } else {
  129.                 while (n-- && lback(lp)!=curbp->b_linep)
  130.                         lp = lback(lp);
  131.         }
  132.         curwp->w_linep = lp;
  133.         curwp->w_flag |= WFHARD;                /* Mode line is OK.     */
  134.         for (i=0; i<curwp->w_ntrows; ++i) {
  135.                 if (lp == curwp->w_dotp)
  136.                         return (TRUE);
  137.                 if (lp == curbp->b_linep)
  138.                         break;
  139.                 lp = lforw(lp);
  140.         }
  141.         lp = curwp->w_linep;
  142.         i  = curwp->w_ntrows/2;
  143.         while (i-- && lp!=curbp->b_linep)
  144.                 lp = lforw(lp);
  145.         curwp->w_dotp  = lp;
  146.         curwp->w_doto  = 0;
  147.         return (TRUE);
  148. }
  149.  
  150. /*
  151.  * This command makes the current
  152.  * window the only window on the screen.
  153.  * Bound to "C-X 1". Try to set the framing
  154.  * so that "." does not have to move on
  155.  * the display. Some care has to be taken
  156.  * to keep the values of dot and mark
  157.  * in the buffer structures right if the
  158.  * distruction of a window makes a buffer
  159.  * become undisplayed.
  160.  */
  161. onlywind(f, n)
  162. register int f, n;
  163. {
  164.         register WINDOW *wp;
  165.         register LINE   *lp;
  166.         register int    i;
  167.  
  168.         while (wheadp != curwp) {
  169.                 wp = wheadp;
  170.                 wheadp = wp->w_wndp;
  171.                 if (--wp->w_bufp->b_nwnd == 0) {
  172.                         wp->w_bufp->b_dotp  = wp->w_dotp;
  173.                         wp->w_bufp->b_doto  = wp->w_doto;
  174.                         wp->w_bufp->b_markp = wp->w_markp;
  175.                         wp->w_bufp->b_marko = wp->w_marko;
  176.                 }
  177.                 free((char *) wp);
  178.         }
  179.         while (curwp->w_wndp != NULL) {
  180.                 wp = curwp->w_wndp;
  181.                 curwp->w_wndp = wp->w_wndp;
  182.                 if (--wp->w_bufp->b_nwnd == 0) {
  183.                         wp->w_bufp->b_dotp  = wp->w_dotp;
  184.                         wp->w_bufp->b_doto  = wp->w_doto;
  185.                         wp->w_bufp->b_markp = wp->w_markp;
  186.                         wp->w_bufp->b_marko = wp->w_marko;
  187.                 }
  188.                 free((char *) wp);
  189.         }
  190.         lp = curwp->w_linep;
  191.         i  = curwp->w_toprow;
  192.         while (i!=0 && lback(lp)!=curbp->b_linep) {
  193.                 --i;
  194.                 lp = lback(lp);
  195.         }
  196.         curwp->w_toprow = 0;
  197.         curwp->w_ntrows = term.t_nrow-1;
  198.         curwp->w_linep  = lp;
  199.         curwp->w_flag  |= WFMODE|WFHARD;
  200.         return (TRUE);
  201. }
  202.  
  203. /*
  204.  * Split the current window. A window
  205.  * smaller than 3 lines cannot be split.
  206.  * The only other error that is possible is
  207.  * a "malloc" failure allocating the structure
  208.  * for the new window. Bound to "C-X 2".
  209.  */
  210. splitwind(f, n)
  211. register int f, n;
  212. {
  213.         register WINDOW *wp;
  214.         register LINE   *lp;
  215.         register int    ntru;
  216.         register int    ntrl;
  217.         register int    ntrd;
  218.         register WINDOW *wp1;
  219.         register WINDOW *wp2;
  220.  
  221.         if (curwp->w_ntrows < 3) {
  222.                 mlwrite("Cannot split a %d line window", curwp->w_ntrows);
  223.                 return (FALSE);
  224.         }
  225.         if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
  226.                 mlwrite("Cannot allocate WINDOW block");
  227.                 return (FALSE);
  228.         }
  229.         ++curbp->b_nwnd;                        /* Displayed twice.     */
  230.         wp->w_bufp  = curbp;
  231.         wp->w_dotp  = curwp->w_dotp;
  232.         wp->w_doto  = curwp->w_doto;
  233.         wp->w_markp = curwp->w_markp;
  234.         wp->w_marko = curwp->w_marko;
  235.         wp->w_flag  = 0;
  236.         wp->w_force = 0;
  237.         ntru = (curwp->w_ntrows-1) / 2;         /* Upper size           */
  238.         ntrl = (curwp->w_ntrows-1) - ntru;      /* Lower size           */
  239.         lp = curwp->w_linep;
  240.         ntrd = 0;
  241.         while (lp != curwp->w_dotp) {
  242.                 ++ntrd;
  243.                 lp = lforw(lp);
  244.         }
  245.         lp = curwp->w_linep;
  246.         if (ntrd <= ntru) {                     /* Old is upper window. */
  247.                 if (ntrd == ntru)               /* Hit mode line.       */
  248.                         lp = lforw(lp);
  249.                 curwp->w_ntrows = ntru;
  250.                 wp->w_wndp = curwp->w_wndp;
  251.                 curwp->w_wndp = wp;
  252.                 wp->w_toprow = curwp->w_toprow+ntru+1;
  253.                 wp->w_ntrows = ntrl;
  254.         } else {                                /* Old is lower window  */
  255.                 wp1 = NULL;
  256.                 wp2 = wheadp;
  257.                 while (wp2 != curwp) {
  258.                         wp1 = wp2;
  259.                         wp2 = wp2->w_wndp;
  260.                 }
  261.                 if (wp1 == NULL)
  262.                         wheadp = wp;
  263.                 else
  264.                         wp1->w_wndp = wp;
  265.                 wp->w_wndp   = curwp;
  266.                 wp->w_toprow = curwp->w_toprow;
  267.                 wp->w_ntrows = ntru;
  268.                 ++ntru;                         /* Mode line.           */
  269.                 curwp->w_toprow += ntru;
  270.                 curwp->w_ntrows  = ntrl;
  271.                 while (ntru--)
  272.                         lp = lforw(lp);
  273.         }
  274.         curwp->w_linep = lp;                    /* Adjust the to